package Q2;

import lombok.SneakyThrows;
import org.junit.Test;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 假设某公司需召开一个视频会议
 * 1）共有 10 名高管参会，
 * 2）只有所有高管均到场后会试才开始。
 * 3）请使用 CountDownLatch（包: java.util.concurrent）
 * 编写一个示例模拟上述情景。
 */
public class Meeting {

    /**
     * Number of executive who attend the meeting
     */
    private final static int ATTENDANCE = 10;

    /**
     * Executive generator
     */
    public List<Executive> executiveGenerator() {
        return Stream.generate(Executive::new).limit(ATTENDANCE).collect(Collectors.toList());
    }

    /**
     * Meeting launcher
     */
    @Test
    @SneakyThrows
    public void launcher() {
        // A synchronization aid that allows one or more threads to wait
        // until a set of operations being performed in other threads completes.
        final CountDownLatch latch = new CountDownLatch(ATTENDANCE);
        executiveGenerator().forEach((executive) -> {
            final ExecutorService executor = Executors.newSingleThreadExecutor();
            executor.execute(() -> {
                try {
                    System.out.printf("> [%d] 还有 [%d] 到场\n", executive.getId(), executive.getTime());
                    Thread.sleep(executive.getTime());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // Decrements the count of the latch, releasing all waiting threads
                // if the count reaches zero.
                latch.countDown();
                System.out.printf("$ [%d] 已到达\n", executive.getId());
            });

            executor.shutdown();
        });

        // Causes the current thread to wait until the latch has counted down to zero,
        // unless the thread is interrupted.
        latch.await();
        System.out.println("> 所有人已到齐，会议开始");
    }

}
